package com.markus.code.动态规划.股票问题;

/**
 * Author:markusZhang
 * Date:Create in 2020/8/20 13:22
 * todo: 最佳买卖股票时机含冷冻期
 */
public class LeetCode_309 {
    /**
     * 这一类的动态规划题有些难
     * 定义profit[i][j]表示在第i天结束之后处于j状态获得的最大收益。
     * 首先我们要知道，第i天选择买入时是不会产生冷冻期状态的，只有再卖出股票时才会产生冷冻期状态的
     * 我们有三种状态可以定义:
     *      1、在第i天结束之后，持有一张股票，获得的最大收益 profit[i][0]
     *      2、在第i天结束之后，没有持有股票，并且处于冷冻期的状态，所获得的最大收益profit[i][1]
     *      3、在第i天结束之后，没有持有股票，并且不处于冷冻期的状态，所获得的最大收益profit[i][2]
     */
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length == 0){
            return 0;
        }
        int profit[][] = new int[prices.length][3];
        //附上初始状态
        //再第0天买入股票，导致现在收益是负数
        profit[0][0] = -prices[0];
        //在第0天不做动作的两种状态
        profit[0][1] = 0;
        profit[0][2] = 0;
        int maxProfit = 0;
        //接下来考虑普通位置
        for (int i=1;i<prices.length;i++){
            //当天买入股票，结束之后所获得的最大收益或者i-1天就已经持有这张股票了
            profit[i][0] = Math.max(profit[i-1][2]-prices[i],profit[i-1][0]);
            //当天结束之后处于冷冻期状态，说明当天卖出股票了,进而来表明第i-1天结束之后必须持有一张股票
            profit[i][1] = profit[i-1][0]+prices[i];
            //当天结束后处于不持有股票并且不处于冷冻期状态所获取的最大收益
            profit[i][2] = Math.max(profit[i-1][1],profit[i-1][2]);
        }
        maxProfit = Math.max(profit[prices.length-1][1],profit[prices.length-1][2]);
        return maxProfit;
    }
}
